//
// Created by dyc on 25-1-9.
//

#include "detector.h"

namespace hitcrt {
    void Detect::detect(cv::Mat &frame) {
        image = frame.clone();
        colorDetect();
        maskProcess(image);
    }

    /**
     * @brief 预处理掩膜消除噪点
     * @param mask
     */
    void Detect::maskProcess(cv::Mat &mask) {
        //高斯滤波
        //cv::GaussianBlur(blackMask,blackMask, cv::Size(3, 3), 0);
        cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
        // 腐蚀操作
        cv::erode(blackMask, blackMask, kernel, cv::Point(-1, -1), MASK_PROCESS_ITERATION);
        // 膨胀操作
        cv::dilate(blackMask, blackMask, kernel, cv::Point(-1, -1), MASK_PROCESS_ITERATION);
    }

    /**
     * @brief 提取颜色生成掩膜
     */
    void Detect::colorDetect() {
        cv::inRange(image, minYellow, maxYellow, yellowMask);
        cv::inRange(image, minBlue, maxBlue, blueMask);
        cv::inRange(image, minBlack, maxBlack, blackMask);
        cv::Mat mask1, mask2;
        cv::inRange(image, minRed_1, maxRed_1, mask1);
        cv::inRange(image, minRed_2, maxRed_2, mask2);
        cv::bitwise_or(mask1, mask2, redMask);
        if (IF_MASK_PROCESS) {
            maskProcess(yellowMask);
            maskProcess(blackMask);
            maskProcess(redMask);
            maskProcess(blueMask);
        }
    };

    /**
     * @brief 检测轮廓端点
     * @param[in] contour       轮廓
     * @param[out] bar           灯条
     */
    void Detect::getEndPointsImpl(const std::vector<cv::Point> &contour) {
        // Done
        cv::Point topmost_point = contour[0];
        cv::Point bottommost_point = contour[0];

        for (const auto &point: contour) {
            if (point.y < topmost_point.y) {
                topmost_point = point;
            }
            if (point.y > bottommost_point.y) {
                bottommost_point = point;
            }
        }
        //bar.m_bottom = bottommost_point;
        //bar.m_top = topmost_point;
    }

    /**
     * @brief 对轮廓进行筛选
     * @param contours 轮廓
     * @return
     */
    int Detect::ContourScreen(std::vector<std::vector<cv::Point>> contours) {
        //从后向前筛选，将不符合条件的轮廓删除
        for (int i =contours.size() - 1; i >= 0; i--) {
            //检验轮廓面积
            double area = cv::contourArea(contours[i]);
            if (area > m_areaMax || area < m_areaMin) {
                contours.erase(contours.begin() + i);
            }

        }
        //检验轮廓点圆度


        //？？？如果两个同色球的图像发生重叠，该如何分开？？？ 尝试使用分水岭算法

        //对轮廓点进行圆形拟合并得到中心点
        
        return 0;
    }

    /**
     * @brief 通过掩模寻找轮廓
     * @return
     */
    bool Detect::findContours() {
        //寻找轮廓
        cv::findContours(yellowMask, contours_yellow, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
        cv::findContours(blackMask, contours_black, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
        cv::findContours(blueMask, contours_blue, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
        cv::findContours(redMask, contours_red, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

        //使用轮廓筛选函数对轮廓进行筛选
        if (!contours_black.empty()) {
            ContourScreen(contours_black);
        }
        if (!contours_red.empty()) {
            ContourScreen(contours_red);
        }
        if (!contours_blue.empty()) {
            ContourScreen(contours_blue);
        }
        if (!contours_yellow.empty()) {
            ContourScreen(contours_yellow);
        }

        return false;
    }




    /**
     * @brief 解算函数，通过轮廓特征点，使用solvePnP解算
     */
    void Detect::Calculator() {
    }


} // hitcrt
